﻿using Commons.Collections;
using NVelocity;
using NVelocity.App;
using NVelocity.Context;
using NVelocity.Runtime;
using System;
using System.IO;
using System.Text;
using System.Web;

namespace HXDNB.Infrastructure.Helper
{
    public class NVelocityHelper : IDisposable
    {
        private VelocityEngine _velocity;
        private IContext _context;

        public IContext Context
        {
            set { _context = value; }
            get { return _context; }
        }

        public NVelocityHelper()
        {
            Init(Config.Template);
        }

        public NVelocityHelper(string templateDir)
        {
            Init(templateDir);
        }

        public void Init(string templateDir)
        {
            //创建VelocityEngine实例对象
            _velocity = new VelocityEngine();

            //使用设置初始化VelocityEngine
            var props = new ExtendedProperties();
            props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
            props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templateDir);
            props.AddProperty(RuntimeConstants.INPUT_ENCODING, "utf-8");
            props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "utf-8");

            _velocity.Init(props);

            //为模板变量赋值
            _context = new VelocityContext();
        }

        public void Put(string key, object value)
        {
            if (_context == null)
            {
                _context = new VelocityContext();
                _context.Put(key, value);
            }
            else
            {
                _context.Put(key, value);
            }
        }

        public StringWriter GetResultString(string templateFileName)
        {
            //从文件中读取模板
            var template = _velocity.GetTemplate(templateFileName);

            //合并模板
            var writer = new StringWriter();
            template.Merge(_context, writer);

            return writer;
        }

        /// <summary>
        /// 显示结果内容
        /// </summary>
        public void Display(string templateFileName)
        {
            StringWriter writer = GetResultString(templateFileName);

            //输出
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Write(writer.ToString());
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        public bool Save(string templateFileName, string path)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(path))
                    return false;

                var writer = GetResultString(templateFileName);

                if (!Directory.Exists(Path.GetDirectoryName(path)))
                    Directory.CreateDirectory(Path.GetDirectoryName(path));

                File.WriteAllText(path, writer.ToString(), Encoding.UTF8);
                return true;
            }
            catch (Exception ex)
            {
                Log.Error("NVelocityHelper.Save", string.Format("文件名:{0}，{1}", templateFileName, ex.Message + ex.StackTrace));
                throw;
            }
        }

        /// <summary>
        /// 部署文件
        /// </summary>
        public bool Deploy(string templateFileName, string relativePath)
        {
            try
            {
                Save(templateFileName, string.Format("{0}/{1}", Config.Preview.TrimEnd('/'), relativePath.TrimStart('/')));
                Save(templateFileName, string.Format("{0}/{1}", Config.Release.TrimEnd('/'), relativePath.TrimStart('/')));
                return true;
            }
            catch (Exception ex)
            {
                Log.Error("NVelocityHelper.Deploy", ex.Message + ex.StackTrace);
                throw;
            }
        }

        public void Dispose()
        {
            if (_velocity == null) return;
            _context = null;
            _velocity = null;
        }
    }
}
